package com.roncoo.education.course.service.api.biz;

import javax.validation.constraints.NotNull;

import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MultiMatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import com.roncoo.education.common.core.base.Page;
import com.roncoo.education.common.core.base.Result;
import com.roncoo.education.common.core.enums.StatusIdEnum;
import com.roncoo.education.common.core.tools.BeanUtil;
import com.roncoo.education.common.core.tools.DateUtil;
import com.roncoo.education.common.elasticsearch.EsPageUtil;
import com.roncoo.education.common.elasticsearch.EsPost;
import com.roncoo.education.common.service.BaseBiz;
import com.roncoo.education.course.dao.PostDao;
import com.roncoo.education.course.dao.impl.mapper.entity.Post;
import com.roncoo.education.course.service.api.req.ApiPostPageReq;
import com.roncoo.education.course.service.api.resp.ApiPostPageResp;

import cn.hutool.core.util.ObjectUtil;
import lombok.RequiredArgsConstructor;

/**
 * API-实验信息
 *
 * @author wujing
 */
@Component
@RequiredArgsConstructor
public class ApiPostBiz extends BaseBiz {

    @NotNull
    private final PostDao dao;

    @NotNull
    private final ElasticsearchRestTemplate elasticsearchRestTemplate;

    public Result<Page<ApiPostPageResp>> searchForPage(ApiPostPageReq req) {
        NativeSearchQueryBuilder nsb = new NativeSearchQueryBuilder();
        // 高亮字段
        nsb.withHighlightFields(new HighlightBuilder.Field("mingcheng").preTags("<mark>").postTags("</mark>"));

        // 分页
        nsb.withPageable(PageRequest.of(req.getPageCurrent() - 1, req.getPageSize()));

        BoolQueryBuilder qb = QueryBuilders.boolQuery();
        qb.must(QueryBuilders.termQuery("statusId", StatusIdEnum.YES.getCode()));
        if (ObjectUtil.isNotEmpty(req.getLeixing())) {
            qb.must(QueryBuilders.termQuery("leixing", req.getLeixing()));
        }
        
        if (StringUtils.hasText(req.getMingcheng())) {
            // 模糊查询multiMatchQuery，最佳字段best_fields
            qb.must(QueryBuilders.multiMatchQuery(req.getMingcheng(), "mingcheng").type(MultiMatchQueryBuilder.Type.BEST_FIELDS));
        } else {
            // 课程排序（sort）
            nsb.withSort(new FieldSortBuilder("postSort").order(SortOrder.ASC));
            nsb.withSort(new FieldSortBuilder("id").order(SortOrder.DESC));
        }
        nsb.withQuery(qb);

        SearchHits<EsPost> searchHits = elasticsearchRestTemplate.search(nsb.build(), EsPost.class, IndexCoordinates.of(EsPost.POST));
        return Result.success(EsPageUtil.transform(searchHits, req.getPageCurrent(), req.getPageSize(), ApiPostPageResp.class));
    }
    
    /**
     * 新闻公告查看接口
     *
     * @param req
     * @param userId
     * @return
     */
    public Result<ApiPostPageResp> view(ApiPostPageReq req) {
        Post post = dao.getById(req.getId());
        if (post == null) {
            return Result.error("找不到该信息");
        }
        boolean isPreview = "1".equals(req.getPreview());
        if (!isPreview && !post.getStatusId().equals(StatusIdEnum.YES.getCode())) {
            return Result.error("该信息已被禁用");
        }
        ApiPostPageResp postResp = BeanUtil.copyProperties(post, ApiPostPageResp.class);
    	postResp.setGmtCreate(DateUtil.fromLocalDateTime(post.getGmtCreate()));
    	postResp.setGmtModified(DateUtil.fromLocalDateTime(post.getGmtModified()));
    	
        return Result.success(postResp);
    }
}
